home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconify-source.lzh / Source / wFileIO.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  13KB  |  558 lines

  1. /*
  2.  *  WICONIFY    A utility that allows you to iconify any Intuition window
  3.  *              on any screen, and to open WB windows on any screen.
  4.  *
  5.  *  wFileIO.c   Handles low-level file activity.
  6.  *
  7.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  8.  *  You may use this code, provided this copyright notice is kept intact.
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <stdio.h>
  13. #include "wFile.h"
  14.  
  15. FILE *InFile;                   /* Main file pointer */
  16. int EndOfFile;                  /* TRUE if at end-of-file */
  17.  
  18. static int LineCount;           /* Number of lines read */
  19. static char Line[MAXLINE+2];    /* Line buffer */
  20. static short LinePos;           /* current position in line */
  21. static short WrdStart,WrdEnd;   /* Where the current word starts and ends */
  22.  
  23. char NextChar;                  /* the next character of the file */
  24. char Word[MAXLINE+1];           /* the word buffer */
  25.  
  26. static FILE *OldFile;           /* Saved file for DEFAULT_ICON command */
  27. static int OldLineCount;        /* Saved line count for old file */
  28.  
  29.  
  30. #define INVERSE     "\033[32;41m"
  31. #define NORMAL      "\033[m"
  32. #define COLORED     "\033[32;40m"
  33.  
  34.  
  35. /*
  36.  *  ShowError()
  37.  *
  38.  *  If the word starts and ends at the same character, move ahead so something
  39.  *    will be displayed.
  40.  *  Get the first character of the word, and end the line there.
  41.  *  Set the text color and print the first part of the line.
  42.  *  Put back the first character of the word, and save the last one.
  43.  *  Print the word in inverted lettering and go back to colored letters.
  44.  *  Put back the last letter of the word and print the rest of the line.
  45.  *  Go back to normal lettering and print the error message with a line number.
  46.  *  If the icon file is open, indicate that.
  47.  */
  48.  
  49. void ShowError(s,x1,x2,x3)
  50. char *s,*x1,*x2,*x3;
  51. {
  52.    char c;
  53.    
  54.    if (WrdStart == WrdEnd) WrdEnd++;
  55.    c = Line[WrdStart]; Line[WrdStart] = 0;
  56.    printf(COLORED);
  57.    printf("%s",Line);
  58.    Line[WrdStart] = c; c = Line[WrdEnd]; Line[WrdEnd] = 0;
  59.    printf(INVERSE); 
  60.    if (EndOfFile || Line[WrdStart] < ' ') printf(" ");
  61.       else printf("%s",&Line[WrdStart]);
  62.    printf(COLORED);
  63.    Line[WrdEnd] = c; if (c) printf("%s",&Line[WrdEnd]); else printf("\n");
  64.    printf(NORMAL);
  65.    printf(s,x1,x2,x3);
  66.    printf(" at line %d",LineCount);
  67.    if (OldFile) printf(" of Icon File");
  68.    printf("\n");
  69. }
  70.  
  71.  
  72. /*
  73.  *  Expected()
  74.  *
  75.  *  If we are at the end of file, indicate this.
  76.  *  If the word is a single character (or no characters)
  77.  *    If the character is printable, use it,
  78.  *    Otherwise, convert it to a word it control character notation.
  79.  *  Print the message saying what was seen and what was expected.
  80.  */
  81.  
  82. void Expected(s)
  83. char *s;
  84. {
  85.    char *Seen = &Word[0];
  86.    char c = Line[WrdStart];
  87.  
  88.    if (EndOfFile) Seen = "End-of-File"; else
  89.    if (WrdEnd < WrdStart+2)
  90.    {
  91.       if ((c >= ' ' && c < 0x7F) || c > 0xA0) Seen = " ", Seen[0] = c;
  92.       else
  93.       {
  94.          switch(c)
  95.          {
  96.             case '\n':
  97.                Seen = "End-of-Line";
  98.                break;
  99.  
  100.             case ' ':
  101.                Seen = "Space";
  102.                break;
  103.  
  104.             case '\t':
  105.                Seen = "TAB";
  106.                break;
  107.  
  108.             case '\033':
  109.                Seen = "ESC";
  110.                break;
  111.  
  112.             case '\0':
  113.                Seen = "NULL";
  114.                break;
  115.  
  116.             case 0x7F:
  117.                Seen = "DEL";
  118.                break;
  119.  
  120.             default:
  121.                Seen = "^ ";
  122.                Seen[1] = (c & 0x1F) + '@';
  123.                break;
  124.          }
  125.       }
  126.    }
  127.    ShowError("'%s' seen where %s was expected",Seen,s);
  128. }
  129.  
  130.  
  131. /*
  132.  *  GetNextLine()
  133.  *
  134.  *  If we can read a line from the file,
  135.  *    Mark the end of line (in case the maximum of the buffer was used)
  136.  *    Clear the position markers, and count the line.
  137.  *    Get the next character on the line.
  138.  *  Otherwise,
  139.  *    Clear the line and set the positions to the end of the line.
  140.  *    Mark the end of file (any error is treated as EOF).
  141.  */
  142.  
  143. static void GetNextLine()
  144. {
  145.    if (fgets(Line,MAXLINE,InFile))
  146.    {
  147.       Line[MAXLINE] = '\n';
  148.       Line[MAXLINE+1] = 0;
  149.       LinePos = WrdStart = WrdEnd = 0;
  150.       LineCount++;
  151.       NextChar = Line[LinePos];
  152.    } else {
  153.       NextChar = '\n'; LinePos = WrdStart = WrdEnd = MAXLINE;
  154.       EndOfFile = TRUE;
  155.    }
  156. }
  157.  
  158.  
  159. /*
  160.  *  GetNextChar()
  161.  *
  162.  *  Get the next character on the line and increment the position.
  163.  *  Set the word positions to the current position.
  164.  */
  165.  
  166. void GetNextChar()
  167. {
  168.    NextChar = Line[++LinePos];
  169.    WrdStart = WrdEnd = LinePos;
  170. }
  171.  
  172.  
  173. /*
  174.  *  SkipComments()
  175.  *
  176.  *  While we are at the beginning of a comment (indicated by '/*')
  177.  *    Move past the comment characters and increment the comment counter
  178.  *    Get the next character.
  179.  *    While we are still within a coment,
  180.  *      and until we reach a comment terminator or end-of-file,
  181.  *        If we are at the end of a line, read the next line,
  182.  *        If we are at the beginning of a nested comment, 
  183.  *          Increment the nexted count and move past the comment characters.
  184.  *        Otherwise, go on to the next character.
  185.  *      If we are at the end of the file, show an error (unbalanced comments).
  186.  *      Otherwise, skip the end-comment characters.
  187.  *      Decrement the comment nesting count.
  188.  *  If the next character is the rest-of-line comment character,
  189.  *    or if we are at the end of the file, move to the end of the line.
  190.  */
  191.  
  192. void SkipComments()
  193. {
  194.    int Nested = 0;
  195.  
  196.    while (NextChar == '/' && Line[LinePos+1] == '*')
  197.    {
  198.       LinePos += 2; Nested++;
  199.       NextChar = Line[LinePos++];
  200.       while (Nested)
  201.       {
  202.          while ((NextChar != '*' || Line[LinePos] != '/') && !EndOfFile)
  203.          {
  204.             if (NextChar == '\n' || NextChar == '\0') GetNextLine(); else
  205.             if (NextChar == '/' && Line[LinePos] == '*')
  206.                Nested++, NextChar = Line[++LinePos];
  207.             else NextChar = Line[LinePos++];
  208.          }
  209.          if (EndOfFile)
  210.          {
  211.             WrdStart = WrdEnd = MAXLINE;
  212.             Expected("End-of-Comment");
  213.          } else NextChar = Line[++LinePos];
  214.          Nested--;
  215.       }
  216.    }
  217.    if (EndOfFile || NextChar == ';') NextChar = Line[LinePos=MAXLINE];
  218. }
  219.  
  220.  
  221. /*
  222.  *  SkipSpaces()
  223.  *
  224.  *  First skip any comments.
  225.  *  While the next character is white-space,
  226.  *    Skip characters until it is not white space,
  227.  *    Then skip comments and do it again.
  228.  */
  229.  
  230. void SkipSpaces()
  231. {
  232.    SkipComments();
  233.    while (NextChar == ' ' || NextChar == '\t')
  234.    {
  235.       do NextChar = Line[++LinePos];
  236.          while (NextChar == ' ' || NextChar == '\t');
  237.       SkipComments();
  238.    }
  239. }
  240.  
  241.  
  242. /*
  243.  *  ReadNextLine()
  244.  *
  245.  *  While there is more in the file, and the current line is blank
  246.  *    Get the next line of the file and skip any comments.
  247.  *    Do this until there is actually some real data to look at.
  248.  *  Set the word positions to the current location.
  249.  */
  250.  
  251. void ReadNextLine()
  252. {
  253.    while (!EndOfFile && (NextChar == 0 || NextChar == '\n'))
  254.    {
  255.       GetNextLine();
  256.       SkipSpaces();
  257.    }
  258.    WrdStart = WrdEnd = LinePos;
  259. }
  260.  
  261.  
  262. /*
  263.  *  SkipChar()
  264.  *
  265.  *  If we are at the end of the line, read the next one,
  266.  *  Otherwise, move to the next non-blank character.
  267.  */
  268.  
  269. void SkipChar()
  270. {
  271.    if (NextChar == '\n') ReadNextLine();
  272.    else NextChar = Line[++LinePos], SkipSpaces();
  273. }
  274.  
  275.  
  276. /*
  277.  *  SkipLine()
  278.  *
  279.  *  No matter where we are on the current line, go on to the next line
  280.  *  and skip spaces.  Mark the current word positions.
  281.  */
  282.  
  283. void SkipLine()
  284. {
  285.    GetNextLine(); SkipSpaces();
  286.    WrdStart = WrdEnd = LinePos;
  287. }
  288.  
  289.  
  290. /*
  291.  *  ReadNextChar()
  292.  *
  293.  *  Get the next character and mark the beginning of a word.
  294.  *  Skip any spaces after the current character.
  295.  */
  296.  
  297. void ReadNextChar()
  298. {
  299.    NextChar = Line[++LinePos];
  300.    WrdStart = WrdEnd = LinePos;
  301.    SkipSpaces();
  302. }
  303.  
  304.  
  305. /*
  306.  *  ReadAWord()
  307.  *
  308.  *  Begin the word at the current location.
  309.  *  While the next character is a letter (or a number if they are allowed)
  310.  *    Add it to the word buffer and go to the next character
  311.  *  If the word has at least one character, mark the end of the word,
  312.  *  Otherwise, the word is a single special character.
  313.  *  Mark the end of the word in the line buffer and skip trailing spaces.
  314.  */
  315.  
  316. void ReadAWord(Numbers)
  317. int Numbers;
  318. {
  319.    short i=0;
  320.    
  321.    WrdStart = LinePos;
  322.    while ((NextChar >= 'A' && NextChar <= 'Z') ||
  323.           (NextChar >= 'a' && NextChar <= 'z') ||
  324.           (NextChar >= '0' && NextChar <= '9' && Numbers) ||
  325.            NextChar == '_')
  326.    {
  327.       Word[i++] = NextChar;
  328.       NextChar = Line[++LinePos];
  329.    }
  330.    if (i)
  331.    {
  332.       Word[i] = 0;
  333.    } else {
  334.       Word[0] = NextChar; Word[1] = 0;
  335.       NextChar = Line[++LinePos];
  336.    }
  337.    WrdEnd = LinePos;
  338.    SkipSpaces();
  339. }
  340.  
  341.  
  342. /*
  343.  *  ReadNextWord()
  344.  *
  345.  *  Read a word without allowing numbers as part of the word.
  346.  */
  347.  
  348. void ReadNextWord()
  349. {
  350.    ReadAWord(FALSE);
  351. }
  352.  
  353.  
  354. /*
  355.  *  ReadExtendedWord()
  356.  *
  357.  *  Read a word and allow numbers as part of the word.
  358.  */
  359.  
  360. void ReadExtendedWord()
  361. {
  362.    ReadAWord(TRUE);
  363. }
  364.  
  365.  
  366. /*
  367.  *  ReadNextInteger()
  368.  *
  369.  *  Get the first digit of the number.
  370.  *  If it is a minus sign, add it to the number and move on.
  371.  *  While the next character is a digit, add it to the number and move on.
  372.  *  Mark the end of the word, and skip blanks.
  373.  */
  374.  
  375. void ReadNextInteger()
  376. {
  377.    short i=0;
  378.    
  379.    NextChar = Line[LinePos=WrdStart];
  380.    if (NextChar == '-')
  381.    {
  382.       Word[i++] = NextChar;
  383.       NextChar = Line[++LinePos];
  384.    }
  385.    while (NextChar >= '0' && NextChar <= '9')
  386.    {
  387.       Word[i++] = NextChar;
  388.       NextChar = Line[++LinePos];
  389.    }
  390.    Word[i] = 0;
  391.    WrdEnd = LinePos;
  392.    SkipSpaces();
  393. }
  394.  
  395.  
  396. /*
  397.  *  ReadFullLine()
  398.  *
  399.  *  Get the first letter of the word.
  400.  *  If the first character is a quote, flag it and move past it.
  401.  *  While we are not at the end of the line (or at an end quote)
  402.  *    Add the character into the word buffer and move on.
  403.  *    If we are looking for a close quote
  404.  *      and the next character is a quoted quote,
  405.  *        add a single quote into the buffer and skip over the quotes.
  406.  *  Mark the end of the word (ie, line).
  407.  *  If we were looking for quotes, then
  408.  *     If we didn't find a closing quote, show an error, otherwise skip
  409.  *       over the close-quote.
  410.  *     Skip blanks after the string.
  411.  *  Otherwise, strip off trailing blanks from the string.
  412.  */
  413.  
  414. void ReadFullLine()
  415. {
  416.    short i = 0;
  417.    int Quoted = FALSE;
  418.  
  419.    NextChar = Line[LinePos=WrdStart];
  420.    if (NextChar == '\'')
  421.    {
  422.       Quoted = TRUE;
  423.       NextChar = Line[WrdStart=++LinePos];
  424.    }
  425.    while (NextChar != '\n' && (NextChar != '\'' || Quoted == FALSE))
  426.    {
  427.       Word[i++] = NextChar;
  428.       NextChar = Line[++LinePos];
  429.       if (Quoted)
  430.       {
  431.          if (NextChar == '\'' && Line[LinePos+1] == '\'')
  432.          {
  433.              Word[i++] = NextChar;
  434.              LinePos += 2;
  435.              NextChar = Line[LinePos];
  436.          }
  437.       }
  438.    }
  439.    WrdEnd = LinePos;
  440.    Word[i--] = 0;
  441.    if (Quoted)
  442.    {
  443.       if (NextChar == '\n') ShowError("Quoted string not terminated");
  444.          else NextChar = Line[++LinePos];
  445.       SkipSpaces();
  446.    } else {
  447.       while (i >= 0 && Word[i] == ' ') Word[i--] = 0;
  448.    }
  449. }
  450.  
  451.  
  452. /*
  453.  *  Reread()
  454.  *
  455.  *  Go back to be beginning of the word and start reading again.
  456.  */
  457.  
  458. void Reread()
  459. {
  460.    LinePos = WrdStart;
  461.    NextChar = Line[LinePos];
  462. }
  463.  
  464.  
  465. /*
  466.  *  WordToUpper()
  467.  *
  468.  *  Look through the word buffer and convert lower case letters to uppper
  469.  *  case ones.
  470.  */
  471.  
  472. void WordToUpper()
  473. {
  474.    char *s = &Word[0];
  475.    
  476.    while (*s)
  477.    {
  478.       if (*s >= 'a' && *s <= 'z') *s = *s - 'a' + 'A';
  479.       s++;
  480.    }
  481. }
  482.  
  483.  
  484. /*
  485.  *  OpenFile()
  486.  *
  487.  *  Attempt to open the specified file.
  488.  *  If successful,
  489.  *    Set the error status and line counters and read the first line
  490.  *  Return TRUE if file openned OK.
  491.  */
  492.  
  493. int OpenFile(Name)
  494. char *Name;
  495. {
  496.    int status = FALSE;
  497.    
  498.    InFile = fopen(Name,"r");
  499.    if (InFile)
  500.    {
  501.       EndOfFile = FALSE; LineCount = 0;
  502.       ReadNextLine();
  503.       status = TRUE;
  504.    }
  505.    return(status);
  506. }
  507.  
  508.  
  509. /*
  510.  *  CloseFile()
  511.  *
  512.  *  Close the file and clear the file pointer.
  513.  */
  514.  
  515. void CloseFile(theFile)
  516. FILE *theFile;
  517. {
  518.    fclose(theFile);
  519.    if (theFile == InFile) InFile = NULL;
  520. }
  521.  
  522.  
  523. /*
  524.  *  SaveOpenFile()
  525.  *
  526.  *  Save the old file pointer and old line count.
  527.  *  Clear the file pointer for future use.
  528.  */
  529.  
  530. void SaveOpenFile()
  531. {
  532.    OldFile = InFile;
  533.    OldLineCount = LineCount;
  534.    InFile = NULL;
  535. }
  536.  
  537.  
  538. /*
  539.  *  RestoreFile()
  540.  *
  541.  *  If there was an old file open,
  542.  *    Get back the old pointer and line count,
  543.  *    Reset the status, and move to the end of the line.
  544.  *    Clear the save pointer for future use.
  545.  */
  546.  
  547. void RestoreFile()
  548. {
  549.    if (OldFile)
  550.    {
  551.       InFile = OldFile;
  552.       LineCount = OldLineCount;
  553.       EndOfFile = FALSE;
  554.       NextChar = Line[LinePos=MAXLINE];
  555.       OldFile = NULL;
  556.    }
  557. }
  558.